package lib.messaging;

import java.io.Serializable;

import lib.ArgumentValidator;

/**
 * Network address of a node
 * @author abhip
 *
 */
public class NetworkAddress implements Serializable, Comparable<NetworkAddress>
{
    /**
     * serialVersionUID is a universal version identifier for a Serializable
     * class. Deserialization uses this number to ensure that a loaded class
     * corresponds exactly to a serialized object. If no match is found during
     * deserialization, an InvalidClassException is thrown.
     */
    private static final long serialVersionUID = 9043999288886408289L;

    private String name;
    private int port;

    public NetworkAddress(String name, int port)
    {
        ArgumentValidator.IsNotNullOrEmpty("name", name);
        ArgumentValidator.IsGreaterThan("port", port, 0);

        this.name = name;
        this.port = port;
    }

    @Override
    public int compareTo(NetworkAddress networkAddress) 
    {
        ArgumentValidator.IsNotNull("networkAddress", networkAddress);
        
        if (this.port == networkAddress.Port())
        {
            return this.name.compareTo(networkAddress.Name());
        }
        
        if (this.port < networkAddress.Port())
        {
            return -1;
        }
        
        return +1;
    }

    @Override public boolean equals(Object obj)
    {
        // Check for self-comparison
        if (this == obj)
        {
            return true;
        }

        // Check for super type matching
        if (!(obj instanceof NetworkAddress))
        {
            return false;
        }

        // Cast to native object is now safe
        NetworkAddress address = (NetworkAddress) obj;

        // Now proper field-by-field comparison can be done
        if (this.name.equals(address.Name()) && this.port == address.Port())
        {
            return true;
        }

        return false;
    }

    public String Name()
    {
        return name;
    }

    public int Port()
    {
        return port;
    }

    @Override
    public String toString()
    {
        return String.format("%s:%d", name, port);
    }
}
